Skip to content
main
Switch branches/tags
jam0001/TeamHTP/
jam0001/TeamHTP/

Latest commit

* npm init

* Initial setup with remarked

* typescript

* quick repl

* tagging and wrapper classes

* tag functions and children

* getMdastContent() overloads

* List update test

* npm start script

* Update README.md

* minor refactor

* Preserve raw markdown for functions

* Preserve tags and functions when serializing

* Add mouthful.{js,lark} and tinker with tsconfig module

* convert lark parser to esm

* Add addItem and removeItem to List

* Appending to paragraphs

* Update File.ts

* Parser and transformer work

* Update index.ts

* Finish parser transformer

* Add semicolons between exprs and add repl grammar

* eval transformed definitions

* repl parser

* repl eval

* fix cascades and repl context

* fix eval

* Saving to disk

* remove member registry from tags

* Remove console logs

* lib updates

* Handle parser error

* Handler repl parse error

* translate native js ops

* Change block to arrow function

* some lib updates and examples

* Update fib.md

* Move prototypes to runtime

* Add helloworld.md

* Change to more family friend\y langauge

* Update examples and log file before REPL

* Add ifTrue and ifFalse to booleans

* Update Heading.ts

* Add more information on readme

* More readme additions

* add isChecked to List

* Update README.md

* final build

Co-authored-by: Tianyi Ma <tn.ma@outlook.com>
988b80e

Git stats

Files

Permalink
Failed to load latest commit information.

bubblegum

A mouthful of bubblegum-flavored-github-flavored-markdown.

What is bubblegum?

Bubblegum lets markdown authors embed code inside comments. These code snippets can be called in a REPL to modify the markdown document on disk. Bubblegum targets github-flavored-markdown and is fully interoperable with existing parsers/renderers.

Markdown has comments?

Kind of...

There is no formal specification for embedding comments in markdown. However, markdown authors will typically use one of two methods when compelled to embed un-rendered text inside their documents: HTML-style comments, and link references. Bubblegum uses the latter for function definitions and element tagging.

Element tagging

In bubblegum, the discrete elements of a markdown document can be tagged for reference at a later time. The following markdown snippet tags a checklist with the name "TodoList":

# Things I have come here to do
[TodoList]::
*   [ ] Chew bubblegum
*   [ ] Kick butt

Any root-level element can be tagged (even other tags!). Tags must have unique names.

Functions

After an element has been tagged, functions can now be defined as members of that tag. Because of the limited (zero) use of parenthesis in this style of commenting, the syntax within bubblegum functions is a Smalltalk-influenced language which we are calling "mouthful".

Building off of the last snippet:

[TodoList]:: (
    completeKickButt
        this CheckItem: 'Kick butt'
)

Once a function has been defined and associated with a tag, that function can now be called from the REPL:

TodoList kickAss

REPL

This repo hosts a TypeScript project which sets up a bubblegum REPL and handles all I/O and parsing necessary to manipulate markdown files with bubblegum. To get started, clone this repo before installing dependencies and running the start script:

$ npm install
$ npm run start demo.md

Development

$ npm install --dev
$ npm run dev # run without building
$ npm run build # build to js

Mouthful Language & Builtins

Many JavaScript features are already accessible, you should be able to 1-to-1 translate our Smalltalk-like Mouthful language to JavaScript.

e.g. console log: 'Hello, World!'

Most syntax follows smalltalk as close as possible. However, there are a few major departures. Such as:

Arrays are written as: @{ 1 2 3 4 5 }

Strings with single quotes: 'this is a string'

And a grouped expression as: ${4 + 4}, not with parenthesis like many other languages.

Here are some additions to overcome some things that can't be 1-to-1 translated:

To access an index on an Array, use:

Array at: index,

e.g. @{ 10 11 12 } at: 2 ==> 12

To get a range of numbers (not inclusive), use: Number to: end,

e.g. 0 to: 10 ==> `@{ 0 1 2 3 4 5 6 7 8 9 }

The not operator for boolean values is: Boolean not,

e.g. true not ==> false

An if is written as: Boolean ifTrue: then,

e.g. 1 < 10 ifTrue: [ console log: 'True!' ] ==> True!

You can also use: Boolean ifFalse: then,

e.g. 10 < 1 ifFalse: [ console log: 'False!' ] ==> False!

The two can be combined like: Boolean ifTrue: trueBranch ifFalse: falseBranch,

e.g. 1 < 10 ifTrue: [ console log: 'True!' ] ifFalse: [ console log: 'False!' ] ==> True!

Library

Bubblegum comes with some handy functions for basic tasks and manipulating markdown elements.

Blockquote

The append function will append some markdown to the end of the element.

MyBlockquote append: 'some **text**'

The text function can be used to either set the text for the contents of the element, or to just return the contents.

MyBlockquote text: 'some **text**'
MyBlockquote text

Code

The append function will append some markdown to the end of the element.

MyCode append: 'some **text**'

The text function can be used to either set the text for the contents of the element, or to just return the contents.

MyCode text: 'some **text**'
MyCode text

The language function can be used to either set the language for the code block, or to just return the language.

MyCode language: 'js'
MyCode language

The eval function will eval the contents of the code block and return the result if the code block language is set to 'js'.

MyCode eval

Heading

The append function will append some markdown to the end of the element.

MyHeading append: 'some **text**'

The text function can be used to either set the text for the contents of the element, or to just return the contents.

MyHeading text: 'some **text**'
MyHeading text

The depth function can be used to either set the heading depth, or to just return the depth. If setting the depth, the desired depth should be an integer from 1-6 (h1 - h6).

MyHeading depth: 1
MyHeading depth

List

The checkItem function will check the first unchecked item in the list whose text matches the argument.

MyList checkItem: 'some **item**'

The uncheckItem function will uncheck the first checked item in the list whose text matches the argument.

MyList uncheckItem: 'some **item**'

The addItem function will add an item to the list with the given text.

MyList addItem: 'some **item**'

The removeItem function will remove the first item from the list whose text matches the argument.

MyList removeItem: 'some **item**'

The removeItemAtIndex function will remove the item at the given index from the list.

MyList removeItemAtIndex: 0

The isChecked function will return if the first item whose text matches the argument and is also a checkbox item is checked. If there are no items in the list matching these criteria then the function will return undefined.

MyList isChecked: 'some **item**'

Paragraph

The append function will append some markdown to the end of the element.

MyParagraph append: 'some **text**'

The text function can be used to either set the text for the contents of the element, or to just return the contents.

MyParagraph text: 'some **text**'
MyParagraph text